文章目录
一.测试代码二.部分代码解释1.在哪里加锁,解锁2.在读写前加 sleep()
三.测试
前面简单得学习了共享内存和信号量,其中信号量的一个重要作用就是对共享资源的保护,保证共享资源在一个时刻只有一个进程独享。那么现在,就来测试一下。
一.测试代码
#include
#include
#include
#include
#include
#include
#include
class CSEM
{
private:
union semun //用于信号灯操作的共同体
{
int val; //信号量的值
struct semid_ds *buf;
unsigned short *arry;
};
int sem_id;
public:
bool init(key_t key); //创建获得、初始化信号量
bool wait(); //等待操作信号量
bool post(); //挂出信号量
bool destroy(); //摧毁信号量
};
int main()
{
int shmid; //共享内存标识
CSEM sem; //创建信号量操作对象;
//信号量,第一步:创建信号量
if ( sem.init(0x5006) == false ) { printf("sem.init failed\n"); return -1; }
printf("sem.init ok\n");
//创建共享内存,第一步:利用shmget
shmid = shmget( (key_t)0x5005, 1024, 0640|IPC_CREAT);
if ( shmid == -1 )
{ printf("shmget() failed\n"); return -1; }
//共享内存,第二步:将共享内存连接到当前的进程 利用 shmat
//获得共享内存的地址,进程可以通过这个地址操作共享空间
char *ptext = 0; //定义一个地址变量,用来存放共享内存的地址
ptext = (char *)shmat(shmid, 0,0);
//对共享内存上锁
if ( sem.wait() == false) { printf("sem.wait failed\n");return -1;}
printf("sem.wait() ok\n");
sleep(30);
//共享内存,第三步:将信息写入共享内存
printf("写入之前,共享内存的内容为%s\n",ptext);
sprintf(ptext, "本程序的进程编号为:%d",getpid() );
printf("写入之后,内容为:%s\n",ptext);
//写完之后,解锁
if (sem.post() == false) { printf("sem.post failed\n"); return -1; }
printf("sem.post() ok\n");
//共享内存,第四步:将共享内存与当前进程分离
shmdt(ptext);
//共享内存,第五步:删除共享内存
//if ( shmctl(shmid, IPC_RMID, 0) == -1)
//{ printf("shmctl(0x5005) failed\n"); return -1; }
}
bool CSEM::init(key_t key)
{
//第一步:先尝试获取信号量,如果信号量不存在就创建信号量
//int sem_id; 别在这里定义,不然这个信号量的标识是局部的。会出错
if ( (sem_id = semget(key,1, 0640)) == -1 ) //信号量不存在吗
{
if (errno == 2) //信号量不存在
{
// 创建信号量
if ( (sem_id = semget(key, 1, 0640|IPC_CREAT)) == -1)
{ perror("init 1 semget()"); return false; }
//创建了信号量,对信号量进行初始化
union semun sem_union;
sem_union.val = 1;
if ( semctl( sem_id, 0, SETVAL, sem_union ) |